<template>
    <div id="container"></div>
</template>

<script lang="ts">
import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
// 引入antv-G6
import G6 from '@antv/g6';

// 弹出层
const tooltip = new G6.Tooltip({
    getContent(e) {
        var tooltipHtml = '';
        var model: any = e.item.getModel();
        // console.log(model, 'model');

        if (model.branchName) {
            tooltipHtml = model.branchNo + ':' + model.branchName + `<br/>` + model.diffValue;
        } else {
            tooltipHtml = String(model['label']); // 显示必须为string类型
        }
        return tooltipHtml;
    },

    itemTypes: ['node'],
    offsetX: 1,
    offsetY: 0,
    fixToNode: true,
    offset: 10,
});

// G6的配置项
G6.registerNode(
    'icon-node',
    {
        // options: {
        //     // size: [60, 40], // 宽高
        //     stroke: '#91d5ff', // 变颜色
        //     fill: '#fff', // 填充色
        //     strokeWidth: 10,
        // },
        // draw是绘制后的附加操作-节点的配置项  图形分组，节点中图形对象的容器
        drawShape(cfg, group) {
            // 获取节点的配置
            const styles = this.getShapeStyle(cfg);
            // console.log(styles, 'styles-----------');

            // 解构赋值
            const { labelCfg = {} } = cfg;
            // console.log(cfg, 'cfg');

            const w = styles.width;
            const h = styles.height;
            // 向分组中添加新的图形 图形 配置 rect矩形 xy 代表左上角坐标 w h是宽高
            const keyShape = group.addShape('rect', {
                attrs: {
                    ...styles,
                    x: -w / 2,
                    y: -h / 2,
                },
            });
            return keyShape;
        },
        // 更新节点后的操作，一般同 afterDraw 配合使用
        update: undefined,
    },
    'rect'
);
G6.registerEdge('flow-line', {
    // 绘制后的附加操作
    draw(cfg, group) {
        // 边两端与起始节点和结束节点的交点；
        const startPoint = cfg.startPoint;
        const endPoint = cfg.endPoint;
        // console.log(startPoint, endPoint, 'endPoint');

        // 边的配置
        const { style } = cfg;
        const shape = group.addShape('path', {
            attrs: {
                stroke: style.stroke, // 边框的样式
                endArrow: style.endArrow, // 结束箭头
                // 路径
                path: [
                    ['M', startPoint.x, startPoint.y],
                    ['L', startPoint.x, (startPoint.y + endPoint.y) / 2],
                    ['L', endPoint.x, (startPoint.y + endPoint.y) / 2],
                    ['L', endPoint.x, endPoint.y],
                ],
            },
        });

        return shape;
    },
});
// 选中时候背景色填充
const defaultStateStyles = {
    selected: {
        fill: '#f39500',
        stroke: '#fff',
        text: {
            fill: '#fff',
        },
    },
};

// 默认节点的颜色 边 圆角的配置
const defaultNodeStyle = {
    fill: '#fff',
    stroke: '#333', // 边框颜色
    radius: 5,
};

// 默认边的颜色 末尾箭头
const defaultEdgeStyle = {
    stroke: '#333', // 边颜色
    endArrow: {
        path: G6.Arrow.triangle(4, 6, 8),
        fill: '#333',
    },
};

// 默认布局
// compactBox 紧凑树布局
// 从根节点开始，同一深度的节点在同一层，并且布局时会将节点大小考虑进去。
const defaultLayout = {
    type: 'compactBox', // 布局类型树
    direction: 'TB', // TB 根节点在上，往下布局
    getId: function getId(d) {
        // 节点 id 的回调函数
        // console.log(d, 'dddddddddddd');
        return d.id;
    },
    getHeight: function getHeight() {
        // console.log('kkkkkkkkkkkkk');
        // 节点高度的回调函数
        return 30;
    },
    getWidth: function getWidth() {
        // console.log('getWidth');
        // 节点宽度的回调函数
        return 16;
    },
    // getVGap: function getVGap() {
    //     // 节点纵向间距的回调函数--垂直间隙
    //     return 60;
    // },
    getHGap: function getHGap() {
        // 节点横向间距的回调函数  水平间隙
        return 70;
    },
};

// 文本配置项
const defaultLabelCfg = {
    style: {
        fill: '#000',
        fontSize: 12,
    },
};

@Component({ name: 'OverBranchFlowChart', components: {} })
export default class OverBranchFlowChart extends Vue {
    tableData: any[] = [];
    proportional: boolean = true; // 是否为比例型
    treedata = {};
    graph = null;
    columnType: string = '';
    async mounted() {
        try {
            await this.getTableData();
        } finally {
            if (Object.keys(this.treedata)?.length) {
                this.G6init();
            }
        }
    }

    G6init() {
        if (typeof window !== 'undefined') {
            window.onresize = () => {
                console.log(container.clientWidth, container.clientHeight, '----------');
                if (!graph || graph.get('destroyed')) return;
                if (!container || !container.scrollWidth || !container.scrollHeight) return;
                graph.changeSize(container.clientWidth, container.clientHeight);
                // graph.clear();
                // window.G6init();
                // graph.data(this.treedata);
                // 根据提供的数据渲染视图。
                graph.render();
                graph.fitView();
                // graph.fitCenter();
            };
        }
        // 获取容器
        const container = document.getElementById('container');
        // 获取容器的宽高
        const width = container.scrollWidth;
        const height = container.scrollHeight || 500;

        // Graph 是 G6 图表的载体-实例化
        const graph = new G6.TreeGraph({
            container: 'container', // 图的 DOM 容器
            width,
            height,
            fitView: true,
            maxZoom: 3,
            linkCenter: true, // 指定边是否连入节点的中心
            plugins: [tooltip], // 插件  minimap
            // fitViewPort: true,
            modes: {
                // 交互模式
                // default 模式中包含点击选中节点行为和拖拽画布行为;
                default: [
                    'scroll-canvas',
                    'hover-node',
                    {
                        type: 'click-select',
                        multiple: false,
                        // 是否允许该 behavior 发生。若返回 false，被操作的 item 不会被选中，也不会触发 'nodeselectchange' 时机事件
                        shouldBegin: (e: any) => {
                            console.log(e, 'eeeeeeeeeee');
                            // 当前节点数据均在e.item.model中
                            let curNode = e.item._cfg.model;
                            // 是否可点击获取详情(0 没有详情  1有详情)
                            return curNode.details == '1';
                        },
                    },
                ],
            },
            // 默认状态下节点的配置
            defaultNode: {
                type: 'icon-node',
                size: [120, 30],
                style: defaultNodeStyle,
                labelCfg: defaultLabelCfg,
            },
            // 默认状态下边的配置，
            defaultEdge: {
                type: 'flow-line',
                style: defaultEdgeStyle,
            },
            // 各个状态下节点的样式-，例如 hover、selected，3.1 版本新增。
            nodeStateStyles: defaultStateStyles,

            // 各个状态下边的样式-，例如 hover、selected，3.1 版本新增。
            edgeStateStyles: defaultStateStyles,
            // 布局配置项
            layout: defaultLayout,
        });
        graph.data(this.treedata);

        // 根据提供的数据渲染视图。
        graph.render();
        // 让画布内容适应视口。
        graph.fitView();
        // 改变视口的缩放比例，在当前画布比例下缩放，是相对比例。
        // graph.zoom(1);

        // 当 click-select 选中的元素集合发生变化时将会触发下面时机事件，evt 中包含相关信息
        graph.on('nodeselectchange', e => {
            // 当前操作的 item
            if (e.target) {
                console.log(e, 'nodeselectchange');
                if (e.target._cfg.model.details == '1') {
                    let model = e.target._cfg.model;
                    // 当前操作后，所有被选中的 items 集合
                    console.log(e.selectedItems);
                    // 当前操作时选中(true)还是取消选中(false)
                    console.log(e.select);
                    // 既然能点击，肯定存在对应的causeType
                    this.columnType = this.getColumnType(e.target._cfg);
                    this.$emit('branch-change', {
                        columnType: this.columnType,
                        serialNo: model.serialNo,
                        branchNo: model.branchNo,
                        detailList: model.detailList,
                    });
                    graph.setItemState(e.target, 'selected', true);
                }
            }
        });

        this.graph = graph;
    }
    /**
     * 表格数据
     */
    private getTableData() {
        return new Promise((resolve, reject) => {
            let params = this.$attrs.searchParams;
            let url = this.$attrs.isFollow ? '/ovattr/oucher/calc' : '/ovattr/oucher/queryCause';
            this.$axios
                .post(url, params)
                .then((res: any) => {
                    this.treedata = {
                        ...res,
                        id: '0',
                        label: res.numeratorDiff + '/' + res.denominatorDiff + '\n' + res.resultDiff,
                        children: this.handleChildren(res.childrenList),
                    };
                    console.log(this.treedata, 'xxxxxxxxxx');
                    resolve(this.treedata);
                })
                .catch(err => {
                    reject(err);
                })
                .finally(() => {
                    // let res = {
                    //     childrenList: [
                    //         {
                    //             causeId: '896973566327853056',
                    //             causeName: '主动',
                    //             causeType: '1',
                    //             childrenList: [
                    //                 {
                    //                     causeId: '896973566327853057',
                    //                     causeName: '基金经理主动操作',
                    //                     causeType: '101',
                    //                     childrenList: [
                    //                         {
                    //                             causeId: '896973566353018880',
                    //                             causeName: '股票',
                    //                             causeType: '10104',
                    //                             date: 20230821,
                    //                             detailList: [
                    //                                 {
                    //                                     amount: 65,
                    //                                     attrValue: 56,
                    //                                     balance: 43,
                    //                                     calculateValue: 45,
                    //                                     causeId: 896973566353018880,
                    //                                     causeType: '1',
                    //                                     detailId: 895103258679529471,
                    //                                     fundCode: '2109',
                    //                                     originalDirection: 'Y',
                    //                                     realDirection: 'Y',
                    //                                     stockCode: '000001 SS',
                    //                                     stockName: '上证指数',
                    //                                 },
                    //                             ],
                    //                             details: '1',
                    //                             influenceValue: 4.040579,
                    //                             parentCauseType: '101',
                    //                             serialNo: '896973566298492928',
                    //                         },
                    //                     ],
                    //                     date: 20230821,
                    //                     details: '0',
                    //                     influenceValue: 4.040579,
                    //                     parentCauseType: '1',
                    //                     serialNo: '896973566298492928',
                    //                 },
                    //             ],
                    //             date: 20230821,
                    //             details: '0',
                    //             influenceValue: 4.040579,
                    //             serialNo: '896973566298492928',
                    //         },
                    //         {
                    //             causeId: '896973566365601792',
                    //             causeName: '被动',
                    //             causeType: '2',
                    //             childrenList: [
                    //                 {
                    //                     causeId: '896973566373990400',
                    //                     causeName: '杂项', // 不能查看详情
                    //                     causeType: '299',
                    //                     date: 20230821,
                    //                     details: '2',
                    //                     influenceValue: -13.96522,
                    //                     parentCauseType: '2',
                    //                     serialNo: '896973566298492928',
                    //                 },
                    //                 {
                    //                     causeId: '896973566365601798',
                    //                     causeName: '证券属性',
                    //                     causeType: '203',
                    //                     childrenList: [
                    //                         {
                    //                             causeId: '896973566369796098',
                    //                             causeName: '评级变动',
                    //                             causeType: '20303',
                    //                             date: 20230821,
                    //                             detailList: [
                    //                                 {
                    //                                     attrType: '3',
                    //                                     attrValue: 464,
                    //                                     calculateValue: 213,
                    //                                     causeId: 896973566369796098,
                    //                                     detailId: 895103258679529471,
                    //                                     stockCode: '000001 SS',
                    //                                     stockName: '上证指数',
                    //                                 },
                    //                             ],
                    //                             details: '1',
                    //                             influenceValue: 8.924642,
                    //                             parentCauseType: '203',
                    //                             serialNo: '896973566298492928',
                    //                         },
                    //                     ],
                    //                     date: 20230821,
                    //                     details: '0',
                    //                     influenceValue: 8.924642,
                    //                     parentCauseType: '2',
                    //                     serialNo: '896973566298492928',
                    //                 },
                    //             ],
                    //             date: 20230821,
                    //             details: '0',
                    //             influenceValue: -5.040579,
                    //             serialNo: '896973566298492928',
                    //         },
                    //     ],
                    //     denominatorDiff: 0,
                    //     numeratorDiff: 0,
                    //     resultDiff: -1,
                    //     serialNo: '896973566298492928',
                    // };
                    // this.treedata = {
                    //     ...res,
                    //     id: '0',
                    //     label: res.numeratorDiff + '/' + res.denominatorDiff + '\n' + res.resultDiff,
                    //     children: this.handleChildren(res.childrenList),
                    // };
                    // console.log(this.treedata, 'xxxxxxxxxx');
                });
        });
    }
    // 处理子节点数据格式 children,id,label
    handleChildren(arr: any) {
        if (!arr) {
            return [];
        }

        return arr.map((ele: any) => {
            // js超长数字溢出问题 js数字最长只支持15位
            ele.id = ele.causeId;
            ele.label = ele.causeName + '\n' + ele.influenceValue;
            ele.children = this.handleChildren(ele.childrenList);
            return ele;
        });
    }

    columnTypeArr = ['101', '201', '202', '203']; // 表格字段展示类型
    getColumnType(_cfg) {
        debugger;
        let model = _cfg.model;
        let ar = this.columnTypeArr.find(ele => ele == model.causeType);
        if (ar) {
            return model.causeType;
        } else {
            return this.getColumnType(_cfg.parent._cfg);
        }
    }
}
</script>
<style scoped>
#container {
    height: calc(100% - 30px);
    width: 100%;
    position: relative;
}
</style>
